Crate argminmax

source ·
Expand description

A crate for finding the index of the minimum and maximum values in an array.

These operations are optimized for speed using SIMD instructions (when available).
The SIMD implementation is branchless, ensuring that there is no best case / worst case. Furthermore, runtime CPU feature detection is used to choose the fastest implementation for the current CPU (with a scalar fallback).

The SIMD implementation is enabled for the following architectures:

§Description

This crate provides two traits: ArgMinMax and NaNArgMinMax.

These traits are implemented for slice and Vec.

  • For ArgMinMax the supported data types are
    • ints: i8, i16, i32, i64
    • uints: u8, u16, u32, u64
    • floats: f16, f32, f64 (see Features)
  • For NaNArgMinMax the supported data types are

Both traits differ in how they handle NaNs:

  • ArgMinMax ignores NaNs and returns the index of the minimum and maximum values in an array.
  • NaNArgMinMax returns the index of the first NaN in an array if there is one, otherwise it returns the index of the minimum and maximum values in an array.

§Caution

When dealing with floats and you are sure that there are no NaNs in the array, you should use ArgMinMax instead of NaNArgMinMax for performance reasons. The former is 5%-30% faster than the latter.

§Features

This crate has several features.

  • nightly_simd (default) - enables the use of AVX512 & (often) NEON SIMD instructions (requires a nightly compiler).
  • float (default) - enables the traits for floats (f32 and f64).
  • half - enables the traits for f16 (requires the half crate).
  • ndarray - adds the traits to ndarray::ArrayBase (requires the ndarray crate).
  • arrow - adds the traits to arrow::array::PrimitiveArray (requires the arrow crate).
  • arrow2 - adds the traits to arrow2::array::PrimitiveArray (requires the arrow2 crate).

§Examples

Two examples are provided below.

§Example with integers

use argminmax::ArgMinMax;

let a: Vec<i32> = vec![0, 1, 2, 3, 4, 5];
let (imin, imax) = a.argminmax();
assert_eq!(imin, 0);
assert_eq!(imax, 5);

§Example with NaNs (default float feature)

use argminmax::ArgMinMax; // argminmax ignores NaNs
use argminmax::NaNArgMinMax; // nanargminmax returns index of first NaN

let a: Vec<f32> = vec![f32::NAN, 1.0, f32::NAN, 3.0, 4.0, 5.0];
let (imin, imax) = a.argminmax(); // ArgMinMax::argminmax
assert_eq!(imin, 1);
assert_eq!(imax, 5);
let (imin, imax) = a.nanargminmax(); // NaNArgMinMax::nanargminmax
assert_eq!(imin, 0);
assert_eq!(imax, 0);

Modules§

  • The strategy that is used to handle the data type.
  • Scalar implementation of the argminmax functions.
  • SIMD implementations of the argminmax functions.

Traits§

  • Trait for finding the minimum and maximum values in an array. For floats, NaNs are ignored.
  • Trait for finding the minimum and maximum values in an array. For floats, NaNs are propagated - index of the first NaN is returned.